class TxtFSM(object):
    def __init__(self):
        self.__state = StateNone()

    def change_to(self,state):
        if self.__state.name == state.name:
            return
        self.__state.leave_state()
        self.__state = state
        self.__state.enter_state()

    def keep_state(self):
        print('cur state is {},will keep'.format(self.__state.name))
        return True

    def cur_state(self):
        return self.__state




# 状态
class State(object):
    name = None

    def __init__(self):
        pass

    def __eq__(self, other):
        if isinstance(other,str):
            return self.name == other
        return self == other

    def __repr__(self):
        return 'state:{}'.format(self.name)

    def leave_state(self):
        pass

    def enter_state(self):
        pass


class StateNone(State):
    name = 'none'

class StateOn(State):
    name = 'on'

    def leave_state(self):
        print('light will be trun off')

    def enter_state(self):
        print('light has been trun on')


class StateOff(State):
    name = 'off'

    def leave_state(self):
        print('light will be trun on')

    def enter_state(self):
        print('light has been trun off')


# event
class Event(object):

    def __init__(self,fsm):
        self._fsm = fsm

    def fire(self):
        pass

class EvtTrunOn(Event):
    def fire(self):
        fsm = self._fsm
        state = fsm.cur_state()
        if state == 'on':
            fsm.keep_state()
        elif  state == 'off':
            fsm.change_to(StateOn())
        elif state == 'none':
            fsm.change_to(StateOn())
        else:
            fsm.keep_state()


class EvtTrunOff(Event):
    def fire(self):
        fsm = self._fsm
        state = fsm.cur_state()
        if state == 'on':
            fsm.change_to(StateOff())
        else:
            fsm.keep_state()


if __name__ == '__main__':
    sm = TxtFSM()
    EvtTrunOff(sm).fire()
    EvtTrunOn(sm).fire()
    EvtTrunOn(sm).fire()
    EvtTrunOff(sm).fire()